package com.mp.netty;

import com.mp.core.utils.SpringUtil;
import com.mp.core.utils.common.NettyCommon;
import com.mp.core.utils.netty.UserChannelRel;
import com.mp.netty.controller.NettyController;
import com.mp.pojo.NO.DataContentNO;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * @author jack
 * @Description: 处理消息的handler
 * TextWebSocketFrame: 在netty中,是用于为websocket专门处理文本的对象,frame是消息的载体
 */
public class NettyHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    /**
     * 用于记录和管理所有客户端的channel对象组
     */
    public static ChannelGroup users =
            new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    private NettyController nettyController = (NettyController) SpringUtil.getBean("nettyController");

    private NettyCommon nettyCommon = (NettyCommon) SpringUtil.getBean("nettyCommon");

    private final Log logger = LogFactory.getLog(this.getClass());


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {

        Channel channel = ctx.channel();

        // 1.获取用户传输的数据并且转化为对象
        DataContentNO dataContent = nettyController.getDataContent(msg, channel);

        // 1.1 为空忽略
        if (dataContent == null) {
            return;
        }

        new Thread() {
            @Override
            public void run() {
                switch (dataContent.getAction()) {
                    case BINDINGCHANNEL:
                        nettyController.binDingChannel(dataContent, channel);
                        break;
                    case KEEPALIVE:
                        System.out.println(dataContent.getAction());
                        break;
                    case FLY_RECORD:
                        nettyController.flyRecord(dataContent);
                        break;
                    default:
                        break;
                }
            }
        }.start();
    }


    /**
     * 当客户端连接服务端之后（打开连接）
     * 获取客户端的channle，并且放到ChannelGroup中去进行管理
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端连接,channelId为: " + ctx.channel().id().asShortText());
        // 将连接的channel加入channel对象组users中
        users.add(ctx.channel());
    }


    /**
     * channel允许活动时
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端允许活动,channelId为: " + ctx.channel().id().asShortText());
    }


    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端被移除,channelId为: " + ctx.channel().id().asShortText());

//        users.remove(ctx.channel().id());
        // channel - 连接对象
//        Channel channel = ctx.channel();
        // 不需要手动remove, netty自动remove
//        channelGroup.remove(addedChannel);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

//        UserChannelRel.get()
        System.out.println("客户端异常,channelId为: " + ctx.channel().id().asShortText());
        // 发生异常时,关闭连接
        // 打印错误信息
        cause.printStackTrace();
        // 发生异常之后关闭连接（关闭channel），随后从ChannelGroup中移除
        ctx.channel().close();
        System.out.println("客户端异常,guanbi");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("wifi网络断了,channelId为: " + ctx.channel().id().asShortText());
        super.channelInactive(ctx);
    }

}
